import xtend from 'xtend';

import {
  getSblxBySbzlx
} from '../../../../mapUtils/SblxUtil';
import {
  randomUUID
} from '../../../../mapUtils/RandomUtil';
import Ipms from './Ipms';
import RuleResult from './vo/RuleResult';

/**
 * 电网线设备修改接口
 * @interface
 * @implements {Ipms}
 */
class IpmsLineString extends Ipms {
  constructor(_tool) {
    super(_tool);
    this.option = null;
    this.timeout = null;
    this.editFlags = {};
  }

  /**
   * 新增电网线设备
   * @override
   * @param {Object} option 默认参数
   * @param {Array} snapList 捕捉图形
   * @param {Array} ignoreSbzlx 捕捉图形中不包含该数组中设备子类型设备
   */
  draw(option, snapList, ignoreSbzlx) {
    this.option = option;
    this.properties.drawtype = this.drawtype;
    this._addProcessEvents();
    this.getTool('EditTool').events.onKeyDown = (e) => {
      console.log('onKeyDown', e);
      if (e.keyCode === 8 || e.keyCode === 46) {
        this.restart();
      }
    };
    return super.draw('snap_line', snapList, ignoreSbzlx);
  }

  /**
   * 编辑电网线设备
   * @override
   * @param {Object} option 默认参数
   * @param {Array} snapList 捕捉图形
   * @param {Array} ignoreSbzlx 捕捉图形中不包含该数组中设备子类型设备
   */
  edit(option, snapList, ignoreSbzlx) {
    this.option = option;
    this.properties.drawtype = this.drawtype;
    let feature = turf.feature(this.option.geometry, Object.assign(this.option, this.properties));
    feature.id = randomUUID();
    // 设置当前绘制的图形
    this.features = [feature];
    this.geometry = feature.geometry;
    this.getTool('EditTool').setEvents({
      onSelectionchange: (e) => {
        if (e.features.length > 0) {
          if (e.features[0] && e.points[0]) {
            this._setEditFlags(e.features[0], e.points[0]);
          }
        } else if (this.editFlags.isEditing) {
          this.drawEnd();
        } else {
          this.stop();
          if (this.events.onReset) {
            this.events.onReset();
          }
        }
      },
      onKeyDown: (e) => {
        if (e.keyCode === 8 || e.keyCode === 46) {
          if (this.getTool('EditTool').getMode() === 'simple_select') {
            if (this.events.onDelete) {
              this.events.onDelete(this.option);
            }
          } else {
            // TODO
          }
        }
      }
    });
    return super.edit('simple_select', feature, snapList, ignoreSbzlx);
  }

  /**
   * 重新开始绘制
   * @override
   */
  restart() {
    this.editFlags = {};
    super.restart();
  }

  /**
   * 添加绘制过程事件
   * @override
   */
  _addProcessEvents() {
    this.getMap().on('click', this._processEvents.onClick);
    this.getMap().on('dblclick', this._processEvents.onDblClick);
    this.getMap().getContainer().addEventListener('keydown', this._processEvents.onKeyDown);
  }

  /**
   * 移除绘制过程事件
   * @override
   */
  _removeProcessEvents() {
    this.getMap().off('click', this._processEvents.onClick);
    this.getMap().off('dblclick', this._processEvents.onDblClick);
    this.getMap().getContainer().removeEventListener('keydown', this._processEvents.onKeyDown);
  }

  /**
   * 鼠标单击事件
   * @override
   */
  _onClick() {
    this._handleOnClick = this.handleOnClick.bind(this);
    if (this._getDrawingFeature()) {
      let tempFeature = JSON.parse(JSON.stringify(this._getDrawingFeature()));
      // 避免双击完成绘制时触发额外的单击事件
      this.timeout = setTimeout(this._handleOnClick, 300, tempFeature);
    }
  }

  /**
   * 鼠标双击事件
   * @override
   */
  _onDblClick() {
    clearTimeout(this.timeout);
  }

  /**
   * 绘制过程点击事件
   * @param {*} tempFeature 正在绘制的图形
   */
  async handleOnClick(tempFeature) {
    let ruleJudgeResult = null;
    // 去掉最后一个点，因为最后一个点和倒数第二个点相同
    tempFeature.geometry.coordinates.length -= 1;
    let index = tempFeature.geometry.coordinates.length - 1;
    // 添加loading
    this.tool.getTop().utils.LoadingUtil.open({
      target: this.tool.getImpl().options.base.container,
      text: 'Loading...',
      spinner: 'el-icon-loading',
      background: 'rgba(23,69,125,0.9)'
    });
    let snap = tempFeature.properties.snaps ? tempFeature.properties.snaps[index] : null;
    ruleJudgeResult = await this._ruleJudgeDrawPoint(index, snap);
    // 去除loading
    this.tool.getTop().utils.LoadingUtil.close();
    this.verificationCallback(ruleJudgeResult);
    if (!ruleJudgeResult.success) {
      this.restart();
    }
    if (this.isDrawEnd) {
      let finalRuleJudgeResult = this._ruleJudgeAllPoint();
      this.verificationCallback(finalRuleJudgeResult);
      if (!finalRuleJudgeResult.success) {
        this.restart();
      } else {

        this._removeProcessEvents();
        this.drawEnd();
      }
    }
  }

  /**
   * 修改完成
   * @override
   * @param {*} e 修改后的数据
   * @ignore
   */
  async updateHandle(e) {
    if (e.action === 'move') {
      console.log('不能拖动整条线');
      return;
    }
    if (this.editFlags.status) {
      // 编辑模式
      this.editFlags.isEditing = true;
      if (this.editFlags.status === 'switch') {
        // 线路改切
        let feature = e.features[0];
        if (feature.geometry.coordinates.length !== this.geometry.coordinates.length) {
          // 如果点数量改变（新增或删除点），并且选中点为末端点，则更改记录的末端点index
          if (this.editFlags.index > 0) {
            if (feature.geometry.coordinates.length > feature.properties.geometry.coordinates.length) {
              if (this.editFlags.index > 0) {
                this.editFlags.switchIndex++;
              }
            } else if (this.editFlags.index > 0) {
              this.editFlags.switchIndex--;
            }
          }
        } else {
          // 如果是线路改切，则记录吸附设备
          this.editFlags.isSwitching = true;
          this.snaps = [feature.properties.snaps[this.editFlags.switchIndex].layer];
        }
      }
      this.features = e.features;
      // 设置当前绘制的图形
      this.geometry = e.features[0].geometry;
    } else {
      // 新增模式
      super.updateHandle(e);
    }

  }

  /**
   * 获取起点设备
   */
  getStartDevice() {
    if (!this.editFlags.status) {
      // 新增模式
      if (this.snaps && this.snaps.length > 0 && this.snaps[0]) {
        let properties = this.snaps[0].properties;
        return xtend({}, properties, {
          sblx: getSblxBySbzlx(properties.sbzlx)
        });
      }
    } else if (this.editFlags.status === 'switch') {
      // 编辑模式-线路改切
      if (this.editFlags.switchDevice === 'Start' && this.snaps && this.snaps[0]) {
        let properties = this.snaps[0].properties;
        return xtend({}, properties, {
          sblx: getSblxBySbzlx(properties.sbzlx)
        });
      }
    } else if (this.editFlags.status === 'editShape') {
      // 编辑模式-修改走向
      return null;
    }
    return null;
  }

  /**
   * 获取终点设备
   */
  getEndDevice() {
    if (!this.editFlags.status) {
      // 新增模式
      if (this.snaps && this.snaps.length > 0 && this.snaps[this.snaps.length - 1]) {
        let properties = this.snaps[this.snaps.length - 1].properties;
        return xtend({}, properties, {
          sblx: getSblxBySbzlx(properties.sbzlx)
        });
      }
    } else if (this.editFlags.status === 'switch') {
      // 编辑模式-线路改切
      if (this.editFlags.switchDevice === 'End' && this.snaps && this.snaps[0]) {
        let properties = this.snaps[0].properties;
        return xtend({}, properties, {
          sblx: getSblxBySbzlx(properties.sbzlx)
        });
      }
    } else if (this.editFlags.status === 'editShape') {
      // 编辑模式-修改走向
      return null;
    }
    return null;
  }

  /**
   * 验证新增点的合理性
   * @ignore
   */
  _ruleJudgeDrawPoint() {}

  /**
   * 验证编辑点的合理性
   * @ignore
   */
  _ruleJudgeEditPoint() {}

  /**
   * 验证所有点合理性
   * @ignore
   */
  _ruleJudgeAllPoint() {}

  /**
   * 设置编辑状态
   * @param {*} feature
   * @param {*} point
   * @ignore
   */
  _setEditFlags(feature, point) {
    // 计算选中点在线中的下标
    let coord = point.geometry.coordinates;
    let index = feature.geometry.coordinates.findIndex((item) => {
      return item[0] === coord[0] && item[1] === coord[1];
    });
    // 判断是否同时编辑线路两端端点
    if (this.editFlags.isSwitching && (index === 0 || index === feature.geometry.coordinates.length - 1) &&
      this.editFlags.switchIndex !== index) {
      this.verificationCallback(new RuleResult(false, index, '只可编辑线路一端端点'));
      setTimeout(() => {
        this.getTool('EditTool').changeMode(this.mode, {
          featureIds: [feature.id]
        });
      }, 200);
      return;
    }
    this.editFlags.index = index;
    // 根据线路端点位置，记录编辑状态
    if (this.editFlags.index === 0 || this.editFlags.index === feature.geometry.coordinates.length - 1) {
      // 如果选中的是首末端点，则找出原端点处的设备
      this.editFlags.status = 'switch';
      this.editFlags.switchIndex = index;
      let xy = this.getMap().project(coord);
      let bounds = [
        [xy.x - 3, xy.y - 3],
        [xy.x + 3, xy.y + 3]
      ];
      let features = this.getMap().queryRenderedFeatures(bounds, {
        layers: this.getTool(this.gridTool)._layerIds
      });
      features.forEach((item) => {
        if (item.geometry.type === 'Point') {
          this._getPointInLinePosition(item.properties, feature.properties);
        }
      });
    } else {
      // 如果选中的是线路中间的端点
      this.editFlags.status = 'editShape';
    }
  }

  /**
   * 获取点设备在线路中的位置
   * @param {Object} point 点设备属性
   * @param {Object} line 线路属性
   * @ignore
   */
  _getPointInLinePosition(point, line) {
    let pointOid = point.ysb_oid;
    if (this._isVirtualPoint(point.sbzlx)) {
      pointOid = point.oid;
    }
    if (pointOid === line.qdsb_oid && point.sbzlx === line.qdsb_sbzlx) {
      this.editFlags.switchDevice = 'Start';
    } else if (pointOid === line.zdsb_oid && point.sbzlx === line.zdsb_sbzlx) {
      this.editFlags.switchDevice = 'End';
    }
  }
}

export default IpmsLineString;